package NG::Gen::Battle::Calc;
use strict;
use warnings;

require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(make_shoot);

use NG::Sys::App;
use Data::Dumper;

sub compare {
	my ($v1,$v2) = @_;
	my $r = rand();
	if($r < 0.05){
		return 1;
	}elsif($r > 0.95){
		return 0;
	}else{
		return disp($v1) > disp($v2);
	}
}
sub disp {
	my $val = shift;
	return $val * (0.8 + 0.4 * rand());
}

sub calc {
	my ($u1,$u2) = @_;
	my $hit;

	my $add_spread;
	if($add_spread = $u1->{add_modif}{spread}){
		$u1->{add_modif}{spread} = 0;
	}else{
		$add_spread = 0;
	}
	my $sub_vulner;
	if($sub_vulner = $u2->{add_modif}{vulner}){
		$u2->{add_modif}{vulner} = 0;
	}else{
		$sub_vulner = 0;
	}

	if($add_spread){
		$hit = 1;
	}elsif(rand(100) > $u2->{mobility}){
		$hit = compare($u1->{aiming},$u2->{stealth});
	}
	unless($hit){
		$hit = rand(100) < $u1->{square};
	}
	my $damag = 0;
	if($hit){
		if(rand(100) < $u1->{accuracy}){
			$damag = $u2->{health};
		}else{
			my $vuln = $u2->{vulner} - $sub_vulner;
			if($vuln < 1){
				$vuln = 1;
			}
			$vuln = disp($vuln)/100;

			my $base = disp($u1->{damage});
			my $spr = disp($u1->{spread} + $add_spread)/100;

			$damag =  sprintf "%.0f", $base * $spr * $vuln;
			if($damag < 0){
				app->logger->info("calc: dmg=$base($u1->{damage}) spr=$spr($u1->{spread},$add_spread) $vuln($u2->{vulner},$sub_vulner)");
			}
		}
	}
	if($damag > $u2->{health} && !$u1->{square}){
		$damag = $u2->{health};
	}
	
	unless(defined $u2->{rest}){
		app->logger->info("rest undef: ".Dumper($u2));
	}
	my $count = 0;
	my $last;
	if($u2->{rest} > $damag){
		$u2->{rest} -= $damag;
	}elsif($u2->{rest} == $damag){
		if($u2->{count}){
			$u2->{rest} = $u2->{health};
			$u2->{count}--;
			$count = 1;
		}else{
			$u2->{rest} = 0;
			$count = 1;
			$last = 1;
		}
	}else{
		if($u2->{count}){
			my $real_damag = 0;
			$count = 0;
			my $ir = $u2->{rest};
			my $ic = $u2->{count};
			my $id = $damag;
			
			while($damag >= $u2->{rest}){
				$damag -= $u2->{rest};
				$real_damag = $u2->{rest};
				$count++;
				if($u2->{count}){
					$u2->{count}--;
					$u2->{rest} = $u2->{health};
				}else{
					$u2->{rest} = 0;
					$last = 1;
					last;
				}
			}
			if($damag < $u2->{rest}){
				$real_damag += $damag;
				$u2->{rest} -= $damag;
			}
			$damag = $real_damag;
			if($damag < 0){
				app->logger->info("id=$id ir=$ir ic=$ic damag=$damag u2->{health}=$u2->{health} u2->{count}=$u2->{count} u2->{rest}=$u2->{rest}");
			}
			
		}else{
			$damag = $u2->{rest};
			$u2->{rest} = 0;
			$count = 1;
			$last = 1;
		}
	}
	return ($last,$count,$damag);
}
sub make_shoot {
	my ($u1,$u2) = @_;
	$u1->{_speed} = $u1->{speed};
	my $total_damag = 0;
	my $total_count = 0;
	my $total_shoot = 0;
	{
		$total_shoot++;
		my ($last,$count,$damag) = calc($u1,$u2);
		$total_damag += $damag;
		$total_count += $count;
		if($last){
			last;
		}
		if(rand(100) < $u1->{_speed}){
			$u1->{_speed} /= 2;
			redo;
		}
	}
	return ($total_shoot,$total_damag,$total_count);
}


1;
